home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 2010 April
/
PCWorld0410.iso
/
pluginy Firefox
/
14439
/
14439.xpi
/
chrome
/
tabber.jar
/
content
/
tabber.js
< prev
next >
Wrap
Text File
|
2009-11-12
|
23KB
|
639 lines
/*
<license>
Tabberwocky - https://addons.mozilla.org/addon/14439/
Copyright (c) 2009 Frank Yan
This file is part of Tabberwocky.
Tabberwocky is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Tabberwocky is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Tabberwocky. If not, see <http://www.gnu.org/licenses/>.
</license>
*/
var tabberwocky = {
io : Cc['@mozilla.org/network/io-service;1'].getService(Ci.nsIIOService),
duplicateTab: function(tab) {
var temp = gBrowser.mPrefs.getBoolPref("tabberwocky.opentabsrelative");
gBrowser.mPrefs.setBoolPref("tabberwocky.opentabsrelative", false);
tabsopenrelative_nextTabShift++;
var newTab = gBrowser.duplicateTab(tab);
newTab.removeAttribute("protected");
gBrowser.moveTabTo(newTab, tab._tPos+1);
gBrowser.mPrefs.setBoolPref("tabberwocky.opentabsrelative", temp);
},
copyTabTitle : function() {
var title = gBrowser.mContextTab.getAttribute('label');
const clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
clipboard.copyString(title);
},
_tabClickingOptions: function() {
gBrowser.mTabContainer.addEventListener("dblclick", function(event) {
if(!gBrowser.mPrefs.getBoolPref('tabberwocky.doubleclicktoclose')) return;
if( event.button == 0 && !event.shiftKey && !event.altKey && !event.ctrlKey && !event.metaKey
&& event.target.localName == "tab"
&& event.target.getAttribute("protected") != "true" ) {
gBrowser.removeTab(event.target);
event.stopPropagation();
}
}, false);
gBrowser.mTabContainer.addEventListener("mousedown", function(event) {
if(this.disabled || event.target.disabled)
return;
if((gBrowser.mPrefs.getBoolPref("tabberwocky.shiftclicktoduplicate"))
&& event.shiftKey && !event.altKey && !event.ctrlKey && !event.metaKey && event.button == 0
&& event.target.localName == "tab" && event.originalTarget.className != "tab-close-button") {
tabberwocky.duplicateTab(event.target);
event.stopPropagation();
}
else if((gBrowser.mPrefs.getIntPref("tabberwocky.altclickshortcut") > 0)
&& event.altKey && !event.shiftKey && !event.ctrlKey && !event.metaKey && event.button == 0
&& event.target.localName == "tab" && event.originalTarget.className != "tab-close-button") {
if((gBrowser.mPrefs.getIntPref("tabberwocky.altclickshortcut") % 2) == 1)
tabberwocky.toggleProtected(event.target);
if(gBrowser.mPrefs.getIntPref("tabberwocky.altclickshortcut") >= 2)
tabberwocky.toggleLocked(event.target);
event.stopPropagation();
}
else if(gBrowser.mPrefs.getBoolPref("tabberwocky.selecttabonclick") && event.button == 0
&& event.target.localName == "tab" && event.originalTarget.className != "tab-close-button")
event.stopPropagation();
}, true);
gBrowser.mTabContainer.addEventListener("click", function(event) {
if(!gBrowser.mPrefs.getBoolPref("tabberwocky.selecttabonclick"))
return;
if(this.disabled || event.target.disabled)
return;
if(!(event.shiftKey && (gBrowser.mPrefs.getBoolPref("tabberwocky.shiftclicktoduplicate")))
&& !(event.altKey && (gBrowser.mPrefs.getIntPref("tabberwocky.altclickshortcut") > 0))
&& event.target.localName == "tab" && event.originalTarget.className != "tab-close-button"
&& event.target != event.target.parentNode.selectedItem && event.button == 0) {
function setTab(tab) {
try {
tab.parentNode._selectNewTab(tab);
} catch(e) {}
}
setTimeout(setTab, 0, event.target);
}
}, false);
},
openLinkInInvertedTab: function() {
var prefStr = "browser.tabs.loadInBackground";
var prefVal = gBrowser.mPrefs.getBoolPref(prefStr);
gBrowser.mPrefs.setBoolPref(prefStr, !prefVal);
gContextMenu.openLinkInTab();
gBrowser.mPrefs.setBoolPref(prefStr, prefVal);
},
_openLinkInInvertedTab: function() {
tabberwocky.openLinkInNewTabLabel = document.getElementById("context-openlinkintab").getAttribute("label");
document.getElementById("contentAreaContextMenu").addEventListener("popupshowing", function() {
if(gBrowser.mPrefs.getIntPref("tabberwocky.openlinkininvertedtab") == 0) {
document.getElementById("context-openlinkintab").setAttribute("label", tabberwocky.openLinkInNewTabLabel);
document.getElementById("tabberwocky-openlinkininvertedtab").hidden = true;
return;
}
var hidden = document.getElementById("context-openlinkintab").hidden;
document.getElementById("tabberwocky-openlinkininvertedtab").hidden = hidden;
if(hidden) return;
var pref = gBrowser.mPrefs.getBoolPref("browser.tabs.loadInBackground");
var strings = document.getElementById("bundle_tabber");
var background = strings.getString("open_link_in_background_tab");
var foreground = strings.getString("open_link_in_foreground_tab");
var d = (pref) ? background : foreground;
var i = (pref) ? foreground : background;
document.getElementById("context-openlinkintab").setAttribute("label", d);
document.getElementById("tabberwocky-openlinkininvertedtab").setAttribute("label", i);
}, false);
},
// Reference: Focus Last Selected Tab by Mike Hokenson <gozer.org/mozilla/extensions/>
_tabClosingOptions: function() {
getBrowser().tabContainer.addEventListener('TabClose', function(e) {
if(e.target.getAttribute("selected") != "true") return;
var pref = gBrowser.mPrefs.getIntPref('tabberwocky.selectonclose');
if(pref != 1 && pref != 2) return;
var tab = e.target;
var tabs = tab.parentNode.childNodes;
var index = 0;
var last = 0;
for(var i = 0; i < tabs.length; i++) {
var s = tabs[i].getAttribute('lastselected');
if(s && s > last && tabs[i] != tab) {
index = i;
last = s;
}
if(tabs[i].getAttribute("selected") == "true" && pref == 1)
break;
}
if(pref == 1) index = (i == 0) ? (tabs.length > 1) ? 1 : 0 : --i;
tab.parentNode.parentNode.parentNode.parentNode.selectedTab = tabs[index];
}, false);
getBrowser().tabContainer.addEventListener('TabSelect', function(e) {
var tab = e.target;
tab.setAttribute('lastselected', new Date().getTime() + tab._tPos);
}, false);
},
// Tab and Tab Bar Attributes
listener: null,
// see http://developer.mozilla.org/en/Code_snippets/Preferences
prefListener: function(branchName, func) {
var prefService = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService);
var branch = prefService.getBranch(branchName);
branch.QueryInterface(Ci.nsIPrefBranch2);
this.register = function() {
branch.addObserver("", this, false);
branch.getChildList("", { }).forEach(function(name) { func(branch, name); });
};
this.unregister = function() {
if(branch)
branch.removeObserver("", this);
};
this.observe = function(subject, topic, data) {
if(topic == "nsPref:changed")
func(branch, data);
};
},
nextGen : Cc["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULAppInfo).version.indexOf("3.5") != 0,
_tabBarAttrs: function() {
if(tabberwocky.nextGen)
multirow.addPrefListener("browser.tabs.insertRelatedAfterCurrent", function(p) {
if(gPrefService.getBoolPref(p))
gPrefService.setBoolPref("tabberwocky.opentabsrelative", false);
});
this.listener = new tabberwocky.prefListener("tabberwocky.",
function(branch, name) {
switch (name) {
case "opentabsrelative":
if(branch.getBoolPref(name) && tabberwocky.nextGen)
gBrowser.mPrefs.setBoolPref("browser.tabs.insertRelatedAfterCurrent", false);
break;
case "newtabbutton":
var tb = document.getElementById("content");
if(!branch.getBoolPref(name))
tb.setAttribute("tabberwocky-hidenewtabbutton", "true");
else
tb.removeAttribute("tabberwocky-hidenewtabbutton");
break;
case "highlightunreadtabs":
var tb = document.getElementById("content");
if(branch.getBoolPref(name))
tb.setAttribute("tabberwocky-highlightunread", "true");
else
tb.removeAttribute("tabberwocky-highlightunread");
break;
case "tabprogressbar":
var tb = document.getElementById("content");
var sp = document.getElementById("statusbar-progresspanel");
if(branch.getBoolPref(name)) {
tb.setAttribute("tabprogressbar", "true");
sp.setAttribute("tabprogressbar-hidden", "true");
}
else {
tb.removeAttribute("tabprogressbar");
sp.removeAttribute("tabprogressbar-hidden");
}
break;
case "duplicatetabkey":
document.getElementById("key_tabberwocky-duplicatetab").setAttribute("disabled", !branch.getBoolPref(name));
break;
case "protecttabkey":
document.getElementById("key_tabberwocky-toggleprotected").setAttribute("disabled", !branch.getBoolPref(name));
break;
case "locktabkey":
document.getElementById("key_tabberwocky-togglelocked").setAttribute("disabled", !branch.getBoolPref(name));
break;
}
}
);
this.listener.register();
window.addEventListener("unload", function() {
tabberwocky.listener.unregister();
}, false);
setTimeout( function() {
gBrowser.selectedTab.setAttribute('lastselected', new Date().getTime() + gBrowser.selectedTab._tPos);
}, 0);
},
// Open Selected Links
// References:
// Tree Style Tab by Piro (piro_or) <addons.mozilla.org/addon/5890>
// Link Bookmarklets <https://www.squarefree.com/bookmarklets/pagelinks.html#open_selected_links>
openSelectedLinks : function(aFrame) {
aFrame = this.getCurrentFrame(aFrame);
var links = this.getSelectedLinks(aFrame);
if(!links.length) return;
links.forEach(function(aLink, aIndex) {
var tab = gBrowser.addTab(aLink.href, this.io.newURI(aFrame.location.href, null, null));
if(aIndex == 0 && !gBrowser.mPrefs.getBoolPref('browser.tabs.loadInBackground'))
gBrowser.selectedTab = tab;
}, this);
},
getCurrentFrame : function(aFrame) {
if(aFrame) return aFrame;
var targetWindow = document.commandDispatcher.focusedWindow;
if(!targetWindow || targetWindow.top == window)
targetWindow = gBrowser.contentWindow;
return targetWindow;
},
getSelectedLinks : function(aFrame) {
aFrame = this.getCurrentFrame(aFrame);
var links = [];
var selection = aFrame.getSelection();
if(!selection || !selection.containsNode) return links;
var docLinks = aFrame.document.links;
if(!docLinks) return links;
for(var i = 0; i < docLinks.length; i++) {
if(selection.containsNode(docLinks[i], true) && this.isSafeLink(docLinks[i].href))
links = links.concat(docLinks[i]);
}
return links;
},
isSafeLink : function(url) {
if(url.substr(0,7) == 'mailto:') return false;
if(url.substr(0,11) == 'javascript:') return false;
return true;
},
_openSelectedLinks : function() {
document.getElementById('contentAreaContextMenu').addEventListener('popupshowing', function() {
var item = document.getElementById('tabberwocky-openselectedlinks');
var hbar = document.getElementById('tabberwocky-openselectedlinks-separator');
if(gBrowser.mPrefs.getBoolPref('tabberwocky.openselectedlinks') && tabberwocky.getSelectedLinks().length) {
var links = tabberwocky.getSelectedLinks();
var label = item.getAttribute('label').split(' (')[0] + ' (' + links.length + ')';
item.setAttribute('label', label);
var box = document.getElementById('tabberwocky-selectedlinks-box');
while(box.firstChild)
box.removeChild(box.firstChild);
links.forEach(function(url, i, l) {
if(i + 1 != l.length && l.length > 20 && box.childNodes.length > 17) {
if(box.childNodes.length == 18) url = '...';
else return;
}
var line = document.createElement('description');
line.setAttribute('crop', 'end');
line.setAttribute('value', url);
box.appendChild(line);
});
item.removeAttribute('hidden');
hbar.removeAttribute('hidden');
}
else {
item.setAttribute('hidden', 'true');
hbar.setAttribute('hidden', 'true');
}
}, false);
},
// Protected Tabs and Locked Tabs
// References:
// Tab Kit by John Mellor (Jomel) <addons.mozilla.org/addon/5447>
// Tabloc by asukaze <http://www.asukaze.net/soft/tabloc/>
toggleProtected : function(tab) {
if(!tab) tab = gBrowser.selectedTab;
if(tab.getAttribute("protected") == "true")
tab.removeAttribute("protected");
else
tab.setAttribute("protected", "true");
},
toggleLocked : function(tab) {
if(!tab) tab = gBrowser.selectedTab;
if(tab.getAttribute("locked") == "true") {
tab.removeAttribute("locked");
tabberwocky.restore_loadURI(gBrowser.getBrowserForTab(tab));
}
else {
tab.setAttribute("locked", "true");
tabberwocky.override_loadURI(gBrowser.getBrowserForTab(tab));
}
},
override_loadURI : function(browser) {
tabberwocky.restore_loadURI(browser);
browser.addEventListener("click", tabberwocky.lockedClick, true);
return;
if(!browser._tabber_loadURI) {
browser._tabber_loadURI = browser.loadURI;
tkLib.prependMethodCode("browser.loadURI", " \
if(gBrowser.selectedTab.hasAttribute('locked')) { \
gBrowser.selectedTab = gBrowser.addTab(aURI, aReferrerURI, aCharset); \
return; \
}");
}
if(!browser._tabber_loadURIWithFlags) {
browser._tabber_loadURIWithFlags = browser.loadURIWithFlags;
tkLib.prependMethodCode("browser.loadURIWithFlags", " \
if(gBrowser.selectedTab.hasAttribute('locked')) { \
gBrowser.selectedTab = gBrowser.addTab(aURI, aReferrerURI, aCharset); \
return; \
}");
}
},
restore_loadURI : function(browser) {
try {
if(browser._tabber_loadURI) {
browser.loadURI = browser._tabber_loadURI;
delete browser._tabber_loadURI;
}
if(browser._tabber_loadURIWithFlags) {
browser.loadURIWithFlags = browser._tabber_loadURIWithFlags;
delete browser._tabber_loadURIWithFlags;
}
browser.removeEventListener("click", tabberwocky.lockedClick, true);
} catch(e) {}
},
lockedClick : function(event) {
if(event && event.target && event.button == 0) {
var a = event.target;
while(a && !a.href && a.tagName && (a.tagName.toLowerCase() != "form"))
a = a.parentNode;
if(a && a.href)
tabberwocky.lockedHref(a, event);
else if(a && a.tagName && a.tagName.toLowerCase() === "form")
tabberwocky.lockedForm(a, event);
}
},
lockedHref : function(a, event) {
if(event.ctrlKey || event.shiftKey || event.metaKey || event.altKey)
return;
if(!gBrowser)
tkLib.beep();
else {
var targethref = tabberwocky.getTargetURL(a).split("#")[0];
if(a.href === targethref || a.href.indexOf(targethref + "#") == 0) return;
if(a.href.indexOf("javascript:") == 0) return;
gBrowser.selectedTab = gBrowser.addTab(a.href, this.io.newURI(a.ownerDocument.URL, null, null));
}
event.stopPropagation();
event.preventDefault();
},
getTargetURL : function(a) {
var target = a.target;
if(target == null || target == "" || target == "_self")
return ""; // avoid reloading page
else if(target == "_blank")
return "";
else if(target == "_top")
return gBrowser.currentURI.spec;
else {
var frames = gBrowser.contentWindow.frames;
for(var i=0; i<frames.length; i++) {
if(frames[i].name == target)
return frames[i].document.location.href;
}
}
return a.ownerDocument.URL;
},
lockedForm : function(a, event) {
a.setAttribute("_lock", a.target);
a.target = "_blank";
a.ownerDocument.defaultView.setTimeout(tabberwocky.unlockForm, 500, a);
},
unlockForm : function(a) {
if(a.hasAttribute("_lock")) {
a.target = a.getAttribute("_lock");
a.removeAttribute("_lock");
}
},
protectedTabClick : function(event) {
if(event.originalTarget.className == "tab-close-button"
&& (event.button == 0 || event.button == 1)
&& event.target.localName == "tab"
&& event.target.getAttribute("protected") == "true")
{
event.target.removeAttribute("protected");
event.stopPropagation();
}
},
ssTabRestored : function(event) {
var tab = event.target;
if(tab.getAttribute("locked") == "true")
tabberwocky.override_loadURI(gBrowser.getBrowserForTab(tab));
},
_protectAndLockTab : function() {
// persist protected and locked attributes across sessions
if("@mozilla.org/browser/sessionstore;1" in Cc) {
var _ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
_ss.persistTabAttribute("protected");
_ss.persistTabAttribute("locked");
}
// initialize protected tabs
tkLib.prependMethodCode('gBrowser.removeTab', 'if(aTab.getAttribute("protected") == "true") { tkLib.beep(); return; }');
tkLib.prependMethodCode('gBrowser.warnAboutClosingTabs', ' \
if(aAll === true) { \
var numProtected = this.mTabContainer.getElementsByAttribute("protected", "true").length; \
if(numProtected > 0) \
return tkLib.warnAboutClosingProtectedTabs(numProtected); \
} \
');
gBrowser.mTabContainer.addEventListener("click", tabberwocky.protectedTabClick, true);
// initialize locked tabs
gBrowser.tabContainer.addEventListener("SSTabRestored", tabberwocky.ssTabRestored, false);
setTimeout(function() {
var _tabs = gBrowser.mTabs;
for(var i = 0; i < _tabs.length; i++) {
if(_tabs[i].getAttribute("locked") == "true")
tabberwocky.override_loadURI(gBrowser.getBrowserForTab(_tabs[i]));
}
}, 500);
},
copyTabHistory : function(fromTab, toTab) {
if(!gBrowser.mPrefs.getBoolPref('tabberwocky.tabhistory')) return;
var from = getBrowser().getBrowserForTab(fromTab).sessionHistory;
var to = getBrowser().getBrowserForTab(toTab).sessionHistory;
to.QueryInterface(Ci.nsISHistoryInternal);
for(var i = 0; i <= from.index; i++)
to.addEntry(from.getEntryAtIndex(i, false), true);
},
_copyTabHistory : function() {
eval("nsBrowserAccess.prototype.openURI = " + nsBrowserAccess.prototype.openURI.toString().replace(
/(var newTab [^;]+;)/, "$1\nif(newTab.owner) tabberwocky.copyTabHistory(newTab.owner, newTab);\n"));
eval("gBrowser.addTab = " + gBrowser.addTab.toString().replace("t.linkedBrowser = b;", "$&\n \
if(!b.sessionHistory.count && aReferrerURI && aReferrerURI.scheme != 'chrome') \
tabberwocky.copyTabHistory(this.mCurrentTab, t);\n"));
},
_openURLBarInTab : function() {
tkLib.addMethodHook([
'gURLBar.handleCommand',
null,
'aTriggeringEvent.altKey',
'(aTriggeringEvent.altKey ^ gPrefService.getBoolPref("tabberwocky.opentabsfromurlbar")) \
&& (gBrowser.currentURI.spec != "about:blank" || gBrowser.webProgress.isLoadingDocument) \
&& (url.indexOf("javascript:") != 0)'
]);
document.getElementById("PopupAutoCompleteRichResult").onPopupClick = function(aEvent) {
if(aEvent.button == 2) return;
var controller = this.view.QueryInterface(Ci.nsIAutoCompleteController), url = "";
try {
url = controller.getValueAt(this.selectedIndex);
} catch(e) {}
if((gPrefService.getBoolPref("tabberwocky.opentabsfromurlbar") && (aEvent.button == 1 || aEvent.ctrlKey || aEvent.metaKey))
|| (gBrowser.currentURI.spec == "about:blank" && !gBrowser.webProgress.isLoadingDocument)
|| url.indexOf("javascript:") == 0) {
controller.handleEnter(true);
return;
}
if(aEvent.button == 0 && !aEvent.shiftKey && !aEvent.ctrlKey && !aEvent.altKey && !aEvent.metaKey) {
if(gPrefService.getBoolPref("tabberwocky.opentabsfromurlbar") && gURLBar && this.mInput == gURLBar) {
this.closePopup();
controller.handleEscape();
gBrowser.selectedTab = gBrowser.addTab(url);
}
else controller.handleEnter(true);
return;
}
if(gURLBar && this.mInput == gURLBar) {
this.closePopup();
controller.handleEscape();
openUILink(url, aEvent);
}
};
tkLib.addMethodHook([
'BrowserSearch.loadSearch',
null,
'(useNewTab)',
'(useNewTab && (gBrowser.currentURI.spec != "about:blank" || gBrowser.webProgress.isLoadingDocument))'
]);
tkLib.prependMethodCode('BrowserSearch.searchBar.doSearch',
'if (gBrowser.currentURI.spec == "about:blank" && !gBrowser.webProgress.isLoadingDocument) aWhere = "current";'
);
},
_tabContextMenu : function() {
function $(id) { return document.getElementById(id); }
var tabContextMenu = gBrowser.mStrip.getElementsByAttribute("anonid", "tabContextMenu")[0];
tabContextMenu.insertBefore($("tabberwocky-duplicatetab"), $("context_newTab").nextSibling);
tabContextMenu.insertBefore($("tabberwocky-toggleprotected"), $("context_reloadTab"));
tabContextMenu.insertBefore($("tabberwocky-togglelocked"), $("context_reloadTab"));
tabContextMenu.insertBefore($("tabberwocky-copytabtitle"), $("context_bookmarkAllTabs").nextSibling);
tabContextMenu.addEventListener("popupshowing", function() {
if(gBrowser.mPrefs.getBoolPref("tabberwocky.duplicatetab"))
document.getElementById("tabberwocky-duplicatetab").removeAttribute("hidden");
else
document.getElementById("tabberwocky-duplicatetab").setAttribute("hidden", "true");
var tab = gBrowser.mContextTab || gBrowser.selectedTab;
var isProtected = tab.getAttribute("protected") == "true";
document.getElementById("context_closeTab").setAttribute('disabled', isProtected);
if(!gBrowser.mPrefs.getBoolPref("tabberwocky.protecttab"))
document.getElementById("tabberwocky-toggleprotected").setAttribute("hidden", "true");
else {
document.getElementById("tabberwocky-toggleprotected").removeAttribute("hidden");
document.getElementById("tabberwocky-toggleprotected").setAttribute("checked", isProtected);
}
if(!gBrowser.mPrefs.getBoolPref("tabberwocky.locktab"))
document.getElementById("tabberwocky-togglelocked").setAttribute("hidden", "true");
else {
document.getElementById("tabberwocky-togglelocked").removeAttribute("hidden");
var isLocked = tab.getAttribute("locked") == "true";
document.getElementById("tabberwocky-togglelocked").setAttribute("checked", isLocked);
}
if(gBrowser.mPrefs.getBoolPref("tabberwocky.copytabtitle"))
document.getElementById("tabberwocky-copytabtitle").removeAttribute("hidden");
else
document.getElementById("tabberwocky-copytabtitle").setAttribute("hidden", "true");
}, false);
},
voila: function() {
tabberwocky._tabClickingOptions();
tabberwocky._openLinkInInvertedTab();
tabberwocky._tabClosingOptions();
tabberwocky._tabBarAttrs();
tabberwocky._openSelectedLinks();
tabberwocky._protectAndLockTab();
tabberwocky._copyTabHistory();
tabberwocky._openURLBarInTab();
tabberwocky._tabContextMenu();
}
}
window.addEventListener("load", tabberwocky.voila, false);